const obj = {name: 'red hat'};

/** 1 如果有三个等号,则不需要进行类型转换,直接比较*/
// console.log(obj === "[object Object]");



/** 2 如果是两个等号,则尝试进行类型转化,再进行比较*/
/*
  NaN和任何值都不相等,包括NaN自身
  null和undefined和其它值都不相等 但它们彼此之间相等
  对象跟字符串比,会把对象转成字符串然后相比 Object.toString()
  其它类型的比较都要转成数字进行比较
*/

/** 2.1 NaN和任何值都不相等,包括NaN自身*/
/*console.log(NaN == true); //false
console.log(NaN == 'abc'); //false
console.log(NaN == NaN); //false
console.log(NaN === NaN); //false
console.log(NaN.toString() === 'NaN'); // true*/

/** 2.2 ull和undefined和其它值都不相等 但它们彼此之间相等*/
/*console.log(null === null); // true
console.log(undefined === undefined); // true
console.log(null === undefined); // false
console.log(null == undefined); // true
console.log(null == '' || null == 0 || null == false); // false
console.log(undefined == '' || undefined == 0 || undefined == false); // false*/

/** 2.3 对象跟字符串比,会把对象转成字符串然后相比 Object.toString()*/
// console.log(obj == "[object Object]"); // true

/** 2.4 其它类型的比较都要转成数字进行比较
 会依次尝试调用
 Number(target.valueOf())
   ↓
 Number(target.toString())

 valueOf和toString这两个方法是每个对象都自带的(继承自Object原型)
 toString会返回一个对象的字符串中描述(类似于这种 [object Object])
 valueOf返回对象本身
 */
/** 2.4 case1*/
// var a = '1';
// console.log(a == 1); // true
//↕等价于
// console.log(Number(a.toString() === 1)); // true

/** 2.4 case2*/
// console.log([] == ![]);
// console.log('[].toString():',[].toString()===''); // true
// console.log(Number([].toString())); // 0
// console.log(![]); // false
// console.log(Number(![])); // 0
//so 0 === 0 ,故 [] == ![]

/** 2.4 case3*/
/*var a = {
  count: 1,
  valueOf() {
    console.log(1); // ← 说明是会先尝试valueOf
    return this.count++;
  },
  toString() {
    console.log(2);
    // return this.count++;
    return this.count++ + 'a';
  }
};
if (a == 1 && a == 2 && a == 3) {
  console.log('ok');
}*/
